package cn.wolfcode.business.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import cn.wolfcode.business.domain.Statement;
import cn.wolfcode.business.mapper.StatementMapper;
import cn.wolfcode.business.util.RegexUtils;
import cn.wolfcode.business.util.VehiclePlateNoUtil;
import cn.wolfcode.common.exception.ServiceException;
import cn.wolfcode.common.utils.DateUtils;
import cn.wolfcode.common.utils.bean.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.wolfcode.business.mapper.AppointmentMapper;
import cn.wolfcode.business.domain.Appointment;
import cn.wolfcode.business.service.IAppointmentService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * 预约信息Service业务层处理
 * 
 * @author dafei
 * @date 2024-03-01
 */
@Service
@Transactional
public class AppointmentServiceImpl implements IAppointmentService 
{
    @Autowired
    private AppointmentMapper appointmentMapper;
    @Autowired
    private StatementMapper statementMapper;

    /**
     * 查询预约信息
     * 
     * @param id 预约信息主键
     * @return 预约信息
     */
    @Override
    public Appointment selectAppointmentById(Long id)
    {
        return appointmentMapper.selectAppointmentById(id);
    }

    /**
     * 查询预约信息列表
     * 
     * @param appointment 预约信息
     * @return 预约信息
     */
    @Override
    public List<Appointment> selectAppointmentList(Appointment appointment)
    {
        return appointmentMapper.selectAppointmentList(appointment);
    }

    /**
     * 新增预约信息
     * 
     * @param appointment 预约信息
     * @return 结果
     */
    @Override
    public int insertAppointment(Appointment appointment)
    {
        // 添加预约单参数校验
        // 是否为空校验
        if(appointment == null){
            throw new ServiceException("参数不合法");
        }
        //断言工具类
        ///Assert.isNull(appointment, "参数异常");

        //此处省略各种参数为空判断---作为拓展，自己写： 可以使用spring-validate 插件实现
        if(appointment.getAppointmentTime() == null){
            throw new ServiceException("预约时间必填");
        }
        // 手机格式合法性校验
        if (!RegexUtils.isPhoneLegal(appointment.getCustomerPhone())){
            throw new ServiceException("手机号码格式不正确！");
        }
        // 车牌号格式校验
        if (VehiclePlateNoUtil.getVehiclePlateNo(appointment.getLicensePlate()) == null){
            throw new ServiceException("车牌号码不合法！");
        }
        // 预约时间大于 当前时简
        if( appointment.getAppointmentTime().getTime() - new Date().getTime() <= 0){
            throw new ServiceException("预约时间不能小于当前时间！");
        }
        /*if(appointment.getAppointmentTime().before(new Date())){
            throw new RuntimeException("预约时间不能小于当前时间！");
        }*/


        //关键字段--手动(自己)控制--state=0
        appointment.setStatus(Appointment.STATUS_APPOINTMENT);



        //方案1：
        appointment.setCreateTime(DateUtils.getNowDate());
        return appointmentMapper.insertAppointment(appointment);
        //方案2：---挑选添加逻辑需要处理的字段，其他不需要处理字段放弃--相对来说， 方案2更安全
       /* Appointment busAppointment1 = new Appointment();
        busAppointment1.setAppointmentTime(appointment.getAppointmentTime());
        busAppointment1.setInfo(appointment.getInfo());
        busAppointment1.setInfo(appointment.getInfo());
        busAppointment1.setInfo(appointment.getInfo());
        busAppointment1.setInfo(appointment.getInfo());
        busAppointment1.setInfo(appointment.getInfo());
        busAppointment1.setInfo(appointment.getInfo());
        busAppointment1.setInfo(appointment.getInfo());
        return appointmentMapper.insertAppointment(busAppointment1);*/
    }

    /**
     * 修改预约信息
     * 
     * @param appointment 预约信息
     * @return 结果
     */
    @Override
    public int updateAppointment(Appointment appointment)
    {
        // 添加预约单参数校验
        // 是否为空校验
        if(appointment == null){
            throw new ServiceException("参数不合法");
        }
        // 判断当前状态是否允许修改
        // 当前预约单状态，必须从数据库中获取
        Appointment app = appointmentMapper.selectAppointmentById(appointment.getId());

        if(app == null){
            throw new ServiceException("参数不合法");
        }
        if(app.getStatus() != Appointment.STATUS_APPOINTMENT){
            throw new ServiceException("只要在预约中状态才允许改动数据");
        }
        //断言工具类
        ///Assert.isNull(appointment, "参数异常");
        //此处省略各种参数为空判断---作为拓展，自己写： 可以使用spring-validate 插件实现
        if(appointment.getAppointmentTime() == null){
            throw new ServiceException("预约时间必填");
        }
        // 手机格式合法性校验
        if (!RegexUtils.isPhoneLegal(appointment.getCustomerPhone())){
            throw new ServiceException("手机号码格式不正确！");
        }
        // 车牌号格式校验
        if (VehiclePlateNoUtil.getVehiclePlateNo(appointment.getLicensePlate()) == null){
            throw new ServiceException("车牌号码不合法！");
        }
        // 预约时间大于 当前时简
        if( appointment.getAppointmentTime().getTime() - new Date().getTime() <= 0){
            throw new ServiceException("预约时间不能小于当前时间！");
        }
        /*if(appointment.getAppointmentTime().before(new Date())){
            throw new RuntimeException("预约时间不能小于当前时间！");
        }*/

        return appointmentMapper.updateAppointment(appointment);
    }

    /**
     * 批量删除预约信息
     * 
     * @param ids 需要删除的预约信息主键
     * @return 结果
     */
    @Override
    public int deleteAppointmentByIds(Long[] ids)
    {
        return appointmentMapper.deleteAppointmentByIds(ids);
    }

    /**
     * 删除预约信息信息
     * 
     * @param id 预约信息主键
     * @return 结果
     */
    @Override
    public int deleteAppointmentById(Long id)
    {
        return appointmentMapper.deleteAppointmentById(id);
    }

    @Override
    public void arralShop(Long id) {
        //判断是否满足操作条件
        Appointment appointment = appointmentMapper.selectAppointmentById(id);
        if(appointment == null){
            throw new ServiceException("参数异常");
        }
        if(appointment.getStatus() != Appointment.STATUS_APPOINTMENT){
            throw new ServiceException("必须是预约中状态才允许执行到店逻辑");
        }
        //执行操作，有哪些表，哪些列，哪些对象涉及改动
        // 到店时间
        // 状态-到店

        //方案1：更新
        appointment.setActualArrivalTime(new Date());
        appointment.setStatus(Appointment.STATUS_ARRIVAL);
        appointmentMapper.updateAppointment(appointment);

        //方案2：定制update-sql
        //appointmentMapper.updatArrivalShop(id, new Date(), Appointment.STATUS_ARRIVAL);
    }

    @Override
    public void cancel(Long id) {
        //判断是否满足操作条件
        Appointment appointment = appointmentMapper.selectAppointmentById(id);
        if(appointment == null){
            throw new ServiceException("参数异常");
        }
        if(appointment.getStatus() != Appointment.STATUS_APPOINTMENT){
            throw new ServiceException("必须是预约中状态才允许执行到店逻辑");
        }
        //执行操作，有哪些表，哪些列，哪些对象涉及改动
        // 到店时间
        // 状态-到店

        //方案1：更新
        appointment.setStatus(Appointment.STATUS_CANCEL);
        appointmentMapper.updateAppointment(appointment);
    }

    @Override
    public Long generateStatement(Long id) {
        //条件
        Appointment appointment = appointmentMapper.selectAppointmentById(id);
        if(appointment == null){
            throw new ServiceException("参数异常");
        }

        if(!(appointment.getStatus()  == Appointment.STATUS_ARRIVAL
                || appointment.getStatus()  == Appointment.STATUS_SETTLE
                || appointment.getStatus()  == Appointment.STATUS_PAYED)){
            throw new ServiceException("不满足生成结算单条件");
        }

        //数据改动--生成结算单

        //判断 结算单是否存在
        Statement statement = statementMapper.selectByAppointmentId(id);

        //存在，返回id
        //不存在， 构建，并返回id
        if(statement == null){
            statement = new Statement();
            //设置其他属性

            BeanUtils.copyProperties(appointment,statement);
            statement.setId(null);
            statement.setStatus(Statement.STATUS_CONSUME);

            statement.setAppointmentId(id);
            statementMapper.insertStatement(statement);

            appointment.setStatus(Appointment.STATUS_SETTLE);  //结算单生成
            appointmentMapper.updateAppointment(appointment);

        }

        return statement.getId();
    }
}
